﻿/*
------------------------------------------------------------------------------
This source file is a part of The Two-Layered GUI Toolkit.

Copyright (c) 2010 - 2013 Florian Haag

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be
included in all copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.
------------------------------------------------------------------------------
 */
using System;

namespace TwoLayeredGUI.Samples.SampleCore
{
	public static partial class Example
	{
		#region message boxes
		public static MessageBoxSettings GetHelloWorldMessage()
		{
			return new MessageBoxSettings(MessageBoxSettings.Information, "Hello World!", ButtonDef.OkButton);
		}
		
		public static MessageBoxSettings GetConfirmationMessage()
		{
			var result = new MessageBoxSettings(MessageBoxSettings.Confirmation, "Do you really want to answer this question?", ButtonDef.YesButton, ButtonDef.NoButton);
			result.Headline = "You have encountered a question.";
			result.ControlButtonLayout = ControlButtonLayout.BottomCenter;
			result.CanRememberChoice = true;
			return result;
		}
		
		private static int DoSomeWork(int lastValue)
		{
			int result = 42 / lastValue;
			DoSomeWork(lastValue - 1);
			return result;
		}
		
		public static MessageBoxSettings GetExceptionMessage()
		{
			try {
				DoSomeWork(5);
				return null;
			}
			catch (Exception ex) {
				return new MessageBoxSettings(ex);
			}
		}
		
		public static MessageBoxSettings GetExceptionWarning()
		{
			try {
				DoSomeWork(3);
				return null;
			}
			catch (Exception ex) {
				return new MessageBoxSettings(MessageBoxSettings.Warning, ex) {
					HideDetails = false
				};
			}
		}
		
		public static MessageBoxSettings GetMessageWithManyButtons()
		{
			return new MessageBoxSettings("Message", "This message box contains awfully many buttons.",
			                              ButtonDef.OkButton, ButtonDef.CancelButton, ButtonDef.SaveButton, ButtonDef.DiscardButton,
			                              ButtonDef.FinishButton, ButtonDef.AbortButton, ButtonDef.IgnoreButton, ButtonDef.RetryButton,
			                              ButtonDef.CloseButton, ButtonDef.CancelButton, ButtonDef.CancelButton, ButtonDef.NoButton,
			                              ButtonDef.YesButton, ButtonDef.NoToAllButton, ButtonDef.YesToAllButton) {
				GroupButtons = true
			};
		}
		
		public static MessageBoxSettings GetLongMessage()
		{
			return new MessageBoxSettings(MessageBoxSettings.Information, "Lorem ipsum dolor sit amet, consectetur adipiscing elit. Maecenas massa magna, porta eu vulputate eu, suscipit non mi. Nunc mauris purus, vestibulum vel consectetur at, laoreet auctor turpis. Etiam pharetra pretium accumsan. Vivamus varius sagittis dictum. Maecenas vel luctus quam. Nulla euismod ante vel lorem feugiat rutrum. Maecenas pulvinar mauris ut tortor pharetra egestas.", ButtonDef.CloseButton);
		}
		
		public static MessageBoxSettings GetConfirmationMessageWithButtonsOnSide()
		{
			var result = new MessageBoxSettings(MessageBoxSettings.Confirmation, "Do you really want to answer this question?", ButtonDef.YesButton, ButtonDef.NoButton);
			result.ControlButtonLayout = ControlButtonLayout.RightSide;
			result.CanRememberChoice = true;
			return result;
		}
		#endregion
		
		#region input boxes
		public static ValueInput.InputBoxSettings GetHelloWorldInput()
		{
			var settings = new ValueInput.InputBoxSettings();
			settings.Title = "Test";
			settings.Values.Add(new ValueInput.StringValue(new AccessString("Example:")));
			return settings;
		}
		
		public static ValueInput.InputBoxSettings GetNameInput()
		{
			var settings = new ValueInput.InputBoxSettings();
			settings.Title = "Name";
			settings.Headline = "A name can be entered here.";
			settings.Values.AddRange(new ValueInput.StringValue(new AccessString("First name:")),
			                         new ValueInput.StringValue(new AccessString("Middle name(s):")) {
			                         	Enabled = false
			                         },
			                         new ValueInput.StringValue(new AccessString("Last name:")));
			settings.ControlButtonLayout = ControlButtonLayout.RightSide;
			return settings;
		}
		
		public static ValueInput.InputBoxSettings GetMultiTypeInput()
		{
			var enumVal = new ValueInput.EnumValue<char>(new AccessString("Selection:", 'e'),
			                                             new char[] { 'A', 'B', 'C', 'D' }
			                                            );
			enumVal.RetrieveDisplayNameFunc += c => "Character '" + c + "'";
			
			var settings = new ValueInput.InputBoxSettings();
			settings.Title = "Types";
			settings.Values.AddRange(new ValueInput.StringValue(new AccessString("String:", 's')),
			                         new ValueInput.Int32Value(new AccessString("Int32:", 'i')),
			                         new ValueInput.BooleanValue(new AccessString("Bool", 'b')),
			                         new ValueInput.SingleValue(new AccessString("Single:", 'n')),
			                         enumVal);
			settings.ControlButtonLayout = ControlButtonLayout.BottomCenter;
			return settings;
		}
		
		private class EvenNumberValidator : ValueInput.Validators.ValueValidator<int>
		{
			protected override void DoValidate(ValueInput.Validators.ValidationInfo<int> info)
			{
				if (info.Value % 2 != 0) {
					AddError("The value {0} is not an even number.", info.Value);
				}
			}
		}
		
		public static ValueInput.InputBoxSettings GetValidatedInput()
		{
			var settings = new ValueInput.InputBoxSettings();
			settings.Title = "Validator Example";
			settings.TopDesc = "The settings in this dialog box are automatically validated and will only be accepted if they pass that validation.";
			settings.Values.Add(new ValueInput.StringValue(new AccessString("Example:"),
			                                               new ValueInput.Validators.RegexStringValidator("^F"),
			                                               new ValueInput.Validators.StringLengthValidator(10)));
			settings.Values.Add(new ValueInput.Int32Value(new AccessString("Even number:"),
			                                              new EvenNumberValidator()) {
			                    	MinValue = -500,
			                    	MaxValue = 1500
			                    });
			return settings;
		}
		
		public static ValueInput.InputBoxSettings GetMultiFontInput()
		{
			var settings = new ValueInput.InputBoxSettings();
			settings.Title = "Fonts Example";
			settings.Values.Add(new ValueInput.StringValue(new AccessString("Normal:")));
			settings.Values.Add(new ValueInput.StringValue(new AccessString("Serif:")) {
			                    	ValueFont = new TwoLayeredGUI.Graphics.Font(TwoLayeredGUI.Graphics.GenericFont.Serif)
			                    });
			settings.Values.Add(new ValueInput.StringValue(new AccessString("Big monospace:")) {
			                    	ValueFont = new TwoLayeredGUI.Graphics.Font(TwoLayeredGUI.Graphics.GenericFont.Monospace, 36)
			                    });
			settings.Values.Add(new ValueInput.StringValue(new AccessString("With serif caption:")) {
			                    	TextFont = new TwoLayeredGUI.Graphics.Font(TwoLayeredGUI.Graphics.GenericFont.Serif)
			                    });
			return settings;
		}
		
		public static ValueInput.InputBoxSettings GetUniqueValuesInput()
		{
			var settings = new ValueInput.InputBoxSettings();
			settings.Title = "Unique Values";
			settings.TopDesc = "None of the values in this dialog box will be accepted more than once.";
			
			var validator = new ValueInput.Validators.UniqueValueValidator<string>();
			for (int i = 0; i < 5; i++) {
				settings.Values.Add(new ValueInput.StringValue(new AccessString("String " + (i + 1).ToString() + ":"), validator));
			}
			
			return settings;
		}
		
		public static ValueInput.InputBoxSettings GetEditCommandsInput(IGUIProvider guiProvider)
		{
			if (guiProvider == null) {
				throw new ArgumentNullException("guiProvider");
			}
			
			var settings = new ValueInput.InputBoxSettings();
			settings.Title = "Edit Commands";
			settings.TopDesc = "Additional editor windows are provided along with these input elements for each value.";
			
			var fileVal = new ValueInput.StringValue(new AccessString("File name:"));
			fileVal.EditCommands.Add(new FileSystem.EditFileNameCommand(guiProvider.FileDialog));
			settings.Values.Add(fileVal);
			
			var classVal = new ValueInput.StringValue(new AccessString("Class name:"),
			                                         new ValueInput.Validators.RegexStringValidator("^[_a-zA-Z][_a-zA-Z0-9]*$"));
			classVal.EditCommands.Add(new ValueInput.Commands.DelegateEditValueCommand<string>(delegate(ref string value) {
			                                                                                   	value = "DefaultClass";
			                                                                                  	return true;
			                                                                                   }, new AccessString("Insert DefaultClass"), null, null));
			settings.Values.Add(classVal);
			
			var dirVal = new ValueInput.StringValue(new AccessString("Directory:"));
			dirVal.EditCommands.Add(new ValueInput.Commands.DelegateEditValueCommand<string>(delegate(ref string value) {
			                                                                                 	value = @"C:\Windows";
			                                                                                 	return true;
			                                                                                 }, new AccessString("Windows Path (Win)"), null, null));
			dirVal.EditCommands.Add(new ValueInput.Commands.DelegateEditValueCommand<string>(delegate(ref string value) {
			                                                                                 	value = "~";
			                                                                                 	return true;
			                                                                                 }, new AccessString("Home Path (Lin)"), null, null));
			dirVal.EditCommands.Add(new FileSystem.EditDirectoryNameCommand(guiProvider.DirectoryDialog, new AccessString("Select Folder...")));
			settings.Values.Add(dirVal);
			
			return settings;
		}
		#endregion
		
		#region progress dialogs
		public static void WorkWithProgress(IProgressDialogController controller, object info)
		{
			for (int i = 0; i <= 100; i++) {
				System.Threading.Thread.Sleep(100);
				controller.AddDetail(i.ToString());
				controller.Progress = i;
				if (i % 20 == 0) {
					controller.StatusMessage = ">= " + i.ToString() + " :-)";
				}
				if (controller.IsCanceled) {
					return;
				}
			}
			System.Threading.Thread.Sleep(100);
			controller.Close();
		}
		
		public static ProgressDialogSettings GetProgressWithoutDetails()
		{
			return new ProgressDialogSettings("Progress", false);
		}
		
		public static ProgressDialogSettings GetProgressWithDetails()
		{
			return new ProgressDialogSettings("Progress With Details", true);
		}
		
		public static ProgressDialogSettings GetProgressWithButton()
		{
			return new ProgressDialogSettings("Progress With a Button", ButtonDef.CancelButton);
		}
		#endregion
	}
}
